package com.zzyl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.zzyl.base.PageResponse;
import com.zzyl.constant.SuperConstant;
import com.zzyl.dto.RoleDto;
import com.zzyl.entity.Role;
import com.zzyl.entity.RoleResource;
import com.zzyl.enums.BasicEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.mapper.RoleMapper;
import com.zzyl.mapper.RoleResourceMapper;
import com.zzyl.mapper.UserRoleMapper;
import com.zzyl.service.RoleService;
import com.zzyl.utils.ObjectUtil;
import com.zzyl.vo.RoleVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class RoleServiceImpl implements RoleService {
    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private UserRoleMapper userRoleMapper;

    @Autowired
    private RoleResourceMapper roleResourceMapper;
    /**
     * 分页查询角色列表信息
     *
     * @param pageNum
     * @param pageSize
     * @param roleDto
     * @return
     */
    @Override
    public PageResponse<RoleVo> page(Integer pageNum, Integer pageSize, RoleDto roleDto) {
        //1. 做好数据的校验和纠错
        if(pageNum <= 0){
            pageNum = 1;
        }
        if(pageSize <=0 || pageSize > 20){
            pageSize = 5;
        }

        //2. 使用PageHelper设置分页参数
        PageHelper.startPage(pageNum, pageSize);

        //3. 调用mapper实现分页的条件查询
        Page<Role> page = roleMapper.selectPage(roleDto);

        //4. 获取并封装结果返回
        PageResponse<RoleVo> pageResponse = new PageResponse<>();
        pageResponse.setPageSize(pageSize);
        pageResponse.setPage(pageNum);
        pageResponse.setTotal(page.getTotal());
        pageResponse.setRecords(BeanUtil.copyToList(page.getResult(),RoleVo.class));

        return pageResponse;
    }

    /**
     * 新增角色
     *
     * @param roleDto
     */
    @Override
    public void insert(RoleDto roleDto) throws CloneNotSupportedException {
       /* Role role = new Role();
        BeanUtils.copyProperties(roleDto, role);*/
        Role role = roleDto.clone();
        role.setCreateTime(LocalDateTime.now());
        role.setUpdateTime(LocalDateTime.now());
        roleMapper.insert(role);
    }

    /**
     * 根据角色id查询对应角色的资源的编码
     *
     * @param roleId
     * @return
     */
    @Override
    public Set<String> findCheckedResources(Long roleId) {
        return roleMapper.findCheckedResources(roleId);
    }

    /**
     * 多种清空的更新
     *
     * @param roleDto
     * @return
     */
    @Override
    public Boolean updateRole(RoleDto roleDto) {
        //1. 根据角色的id查询数据库中旧的数据
        Role role = roleMapper.selectById(roleDto.getId());

        //2. 判断新传递过来的状态和旧数据的状态是否不等 如果不相等则表示 当前是启用/禁用的修改
        if(null != roleDto.getDataState() && !roleDto.getDataState().equals(role.getDataState()) && roleDto.getDataState().equals("1")){
            //2.1 如果是禁用 则先查询当前角色下是否有用户 如果没有用户则允许修改 如果有用户则抛出异常
            Integer count = userRoleMapper.countUser(role.getId());
            if(count > 0){
                throw new BaseException(BasicEnum.ROLE_DISTRIBUTED_DISABLE);
            }
            role.setDataState(roleDto.getDataState());
        }else if(null != roleDto.getDataState()){
            //修改状态
            role.setDataState(roleDto.getDataState());
        }
        if(cn.hutool.core.util.ObjectUtil.isNotEmpty(roleDto.getRoleName())){
            role.setRoleName(roleDto.getRoleName());
        }

        role.setUpdateTime(LocalDateTime.now());
//
        //3. 更新角色表的数据
        roleMapper.updateRole(role);

        //4. 判断资源数组是否为空 如果为空则返回true 如果不为空 需要首先删除角色和资源之间的关系 然后重新插入关系数据
        if(ObjectUtil.isEmpty(roleDto.getCheckedResourceNos())){
            return true;
        }

        //4.1 删除原来老的关系
        roleResourceMapper.deleteByRoleId(role.getId());
        List<RoleResource> list = new ArrayList<>();

        List<RoleResource> roleResourceList = Arrays.asList(roleDto.getCheckedResourceNos()).stream().map(no -> {
            RoleResource roleResource = new RoleResource();
            roleResource.setResourceNo(no);
            roleResource.setRoleId(role.getId());
            roleResource.setDataState(SuperConstant.DATA_STATE_0);
            roleResource.setCreateTime(LocalDateTime.now());
            roleResource.setUpdateTime(LocalDateTime.now());
            return roleResource;
        }).collect(Collectors.toList());


        roleResourceMapper.batchInert(roleResourceList);

        //5. 返回结果
        return true;
    }

    /**
     * 根据角色id删除角色-如果角色是未禁用的则不允许删除
     *
     * @param roleId
     */
    @Override
    public void deleteRoleById(Long roleId) {
        //1. 根据id查询角色信息
        Role role = roleMapper.selectById(roleId);

        //2. 判断当前角色的状态是否是禁用 如果不是则抛出异常
        if(!role.getDataState().equals("1")){
            throw new BaseException(BasicEnum.ROLE_DISTRIBUTED);
        }

        //3. 删除角色和资源的关系
        roleResourceMapper.deleteByRoleId(roleId);

        //4. 删除角色数据
        roleMapper.deleteById(roleId);
    }
}
